home *** CD-ROM | disk | FTP | other *** search
/ Cream of the Crop 26 / Cream of the Crop 26.iso / program / fpkpas92.zip / SRCRTL.ZIP / RTL / DOS / REAL2STR.INC < prev    next >
Text File  |  1997-07-01  |  7KB  |  234 lines

  1. {****************************************************************************
  2.  
  3.                    Copyright (c) 1994,96 by Florian Klämpfl
  4.  
  5.  ****************************************************************************}
  6.  
  7.   procedure str_real(fixkomma : longint;d : real;var s : string);
  8.  
  9.     function mod_rr(z,n : real) : real;
  10.  
  11.       begin
  12.          asm
  13.             fldl n
  14.             fldl z
  15.       Lmod_rr1:
  16.             fprem
  17.             fstsw %ax
  18.             sahf
  19.             jp Lmod_rr1
  20.  
  21.             fstpl __result
  22.             { remove n from stack }
  23.             fstpl n
  24.          end;
  25.       end;
  26.  
  27.     const
  28.        maxexponent = 309;
  29.        maxfract = 16;
  30.  
  31.     var
  32.        buffer : array[0..maxexponent+maxfract+1] of char;
  33.        sign : char;
  34.        p : pchar;
  35.        defprec,pos,i,exponent,aktprec : longint;
  36.        fracfrag,intrest : real;
  37.        hs : string;
  38.        cut : boolean;
  39.  
  40.     begin
  41.        defprec:=maxfract;
  42.        if fixkomma>maxfract then
  43.          fixkomma:=maxfract;
  44.        if d<0 then
  45.          begin
  46.             sign:='-';
  47.             d:=abs(d);
  48.          end
  49.        else
  50.          sign:='+';
  51.        p:=@buffer[maxexponent+maxfract+1];
  52.        fracfrag:=frac(d);
  53.  
  54.        { Vorkommastellen abspalten }
  55.        intrest:=int(d);
  56.        exponent:=0;
  57.        aktprec:=0;
  58.        while intrest>0 do
  59.          begin
  60.             { Attention: this works only for numbers =< 2^31
  61.               p^:=chr(trunc(intrest) mod 10.0)+ord('0'));
  62.             }
  63.             p^:=chr(trunc(mod_rr(intrest,10.0))+ord('0'));
  64.             intrest:=int(intrest/10.0);
  65.             p:=p-1;
  66.             inc(exponent);
  67.             inc(aktprec);
  68.          end;
  69.        p:=p+1;
  70.        for i:=0 to exponent do
  71.          begin
  72.             buffer[i]:=p^;
  73.             p:=p+1;
  74.          end;
  75.  
  76.        { cut seamless digits }
  77.        if aktprec>maxfract then
  78.          aktprec:=maxfract;
  79.  
  80.        { if we need more precision, calculate more digits }
  81.        pos:=exponent;
  82.        if exponent=0 then
  83.          cut:=true
  84.        else cut:=false;
  85.  
  86.        { calculate the digits after the comma }
  87.  
  88.        { +2 because the while condition is aktprec<defprec and we need }
  89.        { one digit to round                                            }
  90.        if fixkomma>=0 then
  91.          defprec:=aktprec+fixkomma+2;
  92.  
  93.        { we can't calulate an infinity precision! }
  94.        if defprec>maxfract then
  95.          defprec:=maxfract;
  96.  
  97.        while aktprec<defprec do
  98.          begin
  99.             fracfrag:=fracfrag*10;
  100.             { sollte der Nachkommateil gleich 0 sein, dann mit 0en auffüllen }
  101.             if fracfrag=0 then
  102.               begin
  103.                  for i:=aktprec to defprec-1 do
  104.                    begin
  105.                       buffer[pos]:='0';
  106.                       inc(aktprec);
  107.                       inc(pos);
  108.                    end;
  109.                  break;
  110.               end;
  111.             buffer[pos]:=chr(trunc(fracfrag)+ord('0'));
  112.  
  113.             { cut leading zeros }
  114.             if (buffer[pos]='0') and (cut) then
  115.               dec(exponent)
  116.             else
  117.               begin
  118.                  cut:=false;
  119.                  inc(aktprec);
  120.                  inc(pos);
  121.               end;
  122.             fracfrag:=frac(fracfrag);
  123.          end;
  124.        dec(aktprec);
  125.  
  126.        buffer[pos]:=#0;
  127.        if ord(buffer[aktprec])>=ord('5') then
  128.          begin
  129.             { Stelle davor 9 ? }
  130.             if buffer[aktprec-1]='9' then
  131.               begin
  132.                  { alle 9en aufrunden }
  133.                  i:=1;
  134.                  while buffer[aktprec-i]='9' do
  135.                    begin
  136.                       buffer[aktprec-i]:='0';
  137.                       inc(i);
  138.                       if i>aktprec then
  139.                         break;
  140.                    end;
  141.                  { 9.9999999eX wird zu 1e(X+1) gerundet }
  142.                  if i>aktprec then
  143.                    begin
  144.                       buffer[0]:='1';
  145.                       inc(exponent);
  146.                    end
  147.                  else
  148.                    buffer[aktprec-i]:=chr(ord(buffer[aktprec-i])+1);
  149.               end
  150.             else buffer[aktprec-1]:=chr(ord(buffer[aktprec-1])+1);
  151.             buffer[aktprec]:=#0;
  152.          end;
  153.        if sign='-' then
  154.          s:='-'
  155.        else
  156.          begin
  157.             if fixkomma>=0 then
  158.               s:=''
  159.             else
  160.               s:=' ';
  161.          end;
  162.        { fixkomma used and fixkomma possible ? }
  163.        if (fixkomma>=0) then
  164.          begin
  165.             { need we a comma ? }
  166.             if exponent<=0 then
  167.               begin
  168.                  s:=s+'0';
  169.                  if fixkomma>0 then
  170.                    s:=s+'.';
  171.  
  172.                  { insert zeros, after the comma }
  173.                  if fixkomma>0 then
  174.                    begin
  175.                       for i:=-1 downto exponent do
  176.                         begin
  177.                            s:=s+'0';
  178.                            dec(aktprec);
  179.                            dec(fixkomma);
  180.                            if fixkomma=0 then
  181.                              break;
  182.                         end;
  183.                    end;
  184.               end;
  185.             p:=@buffer[0];
  186.             while (fixkomma>0) and (aktprec>0) do
  187.               begin
  188.                  s:=s+p^;
  189.                  p:=p+1;
  190.                  dec(aktprec);
  191.                  dec(exponent);
  192.                  if (p^=#0) or (aktprec=0) then
  193.                    begin
  194.                       { fill with zero }
  195.                       for i:=1 to exponent do
  196.                         s:=s+'0';
  197.                       if exponent>=1 then
  198.                         s:=s+'.';
  199.                       for i:=1 to fixkomma do
  200.                         s:=s+'0';
  201.                       break;
  202.                    end;
  203.                  if exponent<0 then
  204.                    dec(fixkomma)
  205.                  else if (exponent=0) then
  206.                    begin
  207.                       { no comma digits ? }
  208.                       if fixkomma=0 then
  209.                          break;
  210.                       s:=s+'.'
  211.                    end;
  212.               end;
  213.          end
  214.        else
  215.          begin
  216.             s:=s+buffer[0]+'.';
  217.             p:=@buffer[1];
  218.             while (p^<>#0) and (aktprec>1) do
  219.               begin
  220.                  s:=s+p^;
  221.                  p:=p+1;
  222.                  dec(aktprec);
  223.               end;
  224.             dec(exponent);
  225.             if exponent<0 then
  226.               sign:='-'
  227.             else sign:='+';
  228.             str(abs(exponent),hs);
  229.             while length(hs)<4 do
  230.               hs:='0'+hs;
  231.             s:=s+'E'+sign+hs;
  232.          end;
  233.     end;
  234.